/**
 * 	 Copyright (c) 2008, 2009 Lukas Zaruba
 * 
 *   This file is part of UniAnalyzer (Universal Analyzer).
 *
 *   UniAnalyzer is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   UniAnalyzer is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with UniAnalyzer. If not, see <http://www.gnu.org/licenses/>.
 */

package net.zarubsys.unianalyzer.dataminers.lpt.gui.wizard;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;

import net.zarubsys.unianalyzer.dataminers.lpt.gui.parameterObject.LPTMeasuringSettings;
import net.zarubsys.unianalyzer.dataminers.lpt.gui.parameterObject.MeasuringSettingsFactory;

import org.apache.log4j.Logger;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.dialogs.WizardNewFileCreationPage;

public class NewLptMeasuringWizard extends Wizard implements INewWizard {
	
	private LPTMeasuringNamePage namePage;
	private WizardNewFileCreationPage fileSelectionPage;
	private LPTMeasuringPortSetUpPage portSetUpPage;
	private LPTMeasuringPinNames pinNames;
	private LPTMeasuringStartNStop startStop;
	
	private ISelection selection;
	
	private static final Logger log = Logger.getLogger(NewLptMeasuringWizard.class);
	
	/* package private */ LPTMeasuringSettings measuringSettings;

	public NewLptMeasuringWizard() {
		super();
		setWindowTitle("LPT measuring");
		setNeedsProgressMonitor(true);
		measuringSettings = MeasuringSettingsFactory.getInstance().getDefaultSettings();
	}
	
	public void addPages() {
		fileSelectionPage = new WizardNewFileCreationPage("fileSelect", (IStructuredSelection) selection);
		fileSelectionPage.setTitle("Select destination");
		fileSelectionPage.setDescription("Select destination where result of measuring will be saved.");
		fileSelectionPage.setFileExtension("lptconf");
		addPage(fileSelectionPage);
		
		portSetUpPage = new LPTMeasuringPortSetUpPage("Port setup");
		portSetUpPage.setTitle("Setup measuring device");
		portSetUpPage.setDescription("Setup necessary values and informations about measuring");
		addPage(portSetUpPage);
		
		pinNames = new LPTMeasuringPinNames("Pins setup");
		pinNames.setTitle("Setup pins");
		pinNames.setDescription("Setup used pins and their names");
		addPage(pinNames);
		
		startStop = new LPTMeasuringStartNStop("Setup start trigger");
		startStop.setTitle("Setup start trigger");
		startStop.setDescription("Setup informations about start trigger");
		addPage(startStop);
		
		namePage = new LPTMeasuringNamePage("Name page");
		namePage.setTitle("Set name and description");
		namePage.setDescription("Set name and description of this measuring configuration.");
		addPage(namePage);
	}

	public boolean performFinish() {
		final IFile file = fileSelectionPage.createNewFile();
		IRunnableWithProgress op = new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor) throws InvocationTargetException {
				try {
					monitor.beginTask("Saving measuring settings...", -1);
					doFinish(file, measuringSettings, monitor);
				} catch (CoreException e) {
					throw new InvocationTargetException(e);
				} finally {
					monitor.done();
				}
			}
		};
		try {
			getContainer().run(true, false, op);
		} catch (InterruptedException e) {
			return false;
		} catch (InvocationTargetException e) {
			Throwable realException = e.getTargetException();
			MessageDialog.openError(getShell(), "Error", realException.getMessage());
			return false;
		}
		return true;
	}
	
	private void doFinish(final IFile file, LPTMeasuringSettings measuringSettings, IProgressMonitor monitor) throws CoreException {
		ObjectOutputStream os = null;
		try {
			os = new ObjectOutputStream(new FileOutputStream(file.getRawLocation().toFile()));
			os.writeObject(measuringSettings);
		} catch (FileNotFoundException e) {
			log.error("Error creating output of new Lpt measuring wizard.", e);
			throwCoreException("Error creating output of new Lpt measuring wizard.");
		} catch (IOException e) {
			log.error("Error creating output of new Lpt measuring wizard.", e);
			throwCoreException("Error creating output of new Lpt measuring wizard.");
		} finally {
			try {
				os.close();
			} catch (IOException e) {
				log.error("Error closing output stream of new Lpt measuring wizard.", e);
				throwCoreException("Error closing output stream of new Lpt measuring wizard.");
			}
		}
	}
	
	private void throwCoreException(String message) throws CoreException {
		IStatus status = new Status(IStatus.ERROR, "net.zarubsys.unianalyzer.dataminers.lpt.gui", IStatus.OK, message, null);
		throw new CoreException(status);
	}

	public void init(IWorkbench workbench, IStructuredSelection selection) {
		this.selection = selection;
	}
	
}